package com.example.himalaya.presenters;

import android.widget.Toast;

import com.example.himalaya.base.BaseApplication;
import com.example.himalaya.model.dao.HistoryDao;
import com.example.himalaya.view.callback.IHistoryViewCallback;
import com.example.himalaya.presenters.interfaces.IHistoryPresenter;
import com.example.himalaya.view.callback.IHistoryDaoCallback;
import com.example.himalaya.constants.Constants;
import com.example.himalaya.utils.LogUtil;
import com.ximalaya.ting.android.opensdk.model.track.Track;

import java.util.ArrayList;
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.schedulers.Schedulers;

public class HistoryPresenter implements IHistoryPresenter, IHistoryDaoCallback {

    // Constant
    private static final String TAG = "HistoryPresenter";

    // Global variable
    private Track mCurrentTrack;


    //List
    private List<IHistoryViewCallback> mCallbacks = new ArrayList<>();
    private List<Track> mData;

    // Logic object
    private static HistoryPresenter sHistoryPresenter = null;
    private final HistoryDao mHistoryDao;

    // Flag
    private boolean mIsOutOfSize = false;

    private HistoryPresenter() {
        // init data
        mData = new ArrayList<>();

        // create logic object
        mHistoryDao = new HistoryDao();

        // register callback
        mHistoryDao.setCallback(this);

        // init data (get data from db)
        listHistories();
    }

    public static HistoryPresenter getInstance() {

        if (sHistoryPresenter == null) {
            synchronized (HistoryPresenter.class) {
                if (sHistoryPresenter == null) {
                    sHistoryPresenter = new HistoryPresenter();
                }
            }
        }

        return sHistoryPresenter;
    }

    @Override
    public void listHistories() {
        Observable.create(new ObservableOnSubscribe<Object>() {

            @Override
            public void subscribe(ObservableEmitter<Object> emitter) throws Exception {
                mHistoryDao.listHistories();
            }
        }).subscribeOn(Schedulers.io()).subscribe();
    }

    @Override
    public void addHistory(final Track track) {

        // 判断是否满足用户限制
        if (mData != null) {
            if (mData.size() > Constants.MAX_HISTORY_COUNT) {
                Toast.makeText(BaseApplication.getAppContext(), "听的歌太多，需要删除一首老歌了", Toast.LENGTH_LONG).show();


                this.mCurrentTrack = track;
                mIsOutOfSize = true;


                delHistory(mData.get(mData.size() - 1));
            } else {
                doAddHistory(track);
            }
        }
    }

    private void doAddHistory(final Track track) {


        Observable.create(new ObservableOnSubscribe<Object>() {

            @Override
            public void subscribe(ObservableEmitter<Object> emitter) throws Exception {
                mHistoryDao.addHistory(track);
            }
        }).subscribeOn(Schedulers.io()).subscribe();
    }

    private boolean IfHaveHistory(Track track) {


        for (Track item : mData) {
            if (item.getDataId() == track.getDataId()) {
                return true;
            }
        }

        return false;
    }

    @Override
    public void delHistory(final Track track) {
        Observable.create(new ObservableOnSubscribe<Object>() {

            @Override
            public void subscribe(ObservableEmitter<Object> emitter) throws Exception {
                mHistoryDao.delHistory(track);
            }
        }).subscribeOn(Schedulers.io()).subscribe();
    }

    @Override
    public void clearHistoriesClean() {
        Observable.create(new ObservableOnSubscribe<Object>() {

            @Override
            public void subscribe(ObservableEmitter<Object> emitter) throws Exception {
                mHistoryDao.clearHistory();
            }
        }).subscribeOn(Schedulers.io()).subscribe();
    }


    @Override
    public void registerViewCallback(IHistoryViewCallback iHistoryViewCallback) {
        if (!mCallbacks.contains(iHistoryViewCallback)) {
            mCallbacks.add(iHistoryViewCallback);
        }
    }

    @Override
    public void unRegisterViewCallback(IHistoryViewCallback iHistoryViewCallback) {
        mCallbacks.remove(iHistoryViewCallback);
    }


    @Override
    public void onHistoryAdd(boolean isSuccess) {
        // nothing to do
        listHistories();
    }

    @Override
    public void onHistoryDel(boolean isSuccess) {

        if (mIsOutOfSize) {

            // The flag is work
            mIsOutOfSize = false;

            doAddHistory(mCurrentTrack);
        } else {
            listHistories();
        }

    }

    @Override
    public void onHistoriesLoaded(final List<Track> tracks) {

        if (mData != null) {
            mData.clear();

            mData.addAll(tracks);
        }

        for (Track track : tracks) {
            LogUtil.d(TAG, "track title" + track.getTrackTitle());
        }


        // 通知UI更新数据
        // 从IO 线程到 主线程
        BaseApplication.getsHandler().post(new Runnable() {
            @Override
            public void run() {
                for (IHistoryViewCallback callback : mCallbacks) {
                    callback.onHistoriesLoaded(tracks);
                }
            }
        });
    }

    @Override
    public void onHistoriesClean(boolean isSuccess) {
        // nothing to do
        listHistories();
    }
}
